package org.compiere.process;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Calendar;

import org.adempiere.exceptions.AdempiereException;
import org.compiere.model.Mhrmemployee;
import org.compiere.model.Mhrmlimitholiday;
import org.compiere.model.Mhrmorder;
import org.compiere.model.Mhrmreserve;
import org.compiere.model.Mhrmreservesectional;
import org.compiere.model.Mhrmreview;
import org.compiere.model.Mhrmreviewline;
import org.compiere.model.X_hrm_order;
import org.compiere.model.X_hrm_reviewline;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.eevolution.model.X_HR_Employee;

import extend.org.compiere.hrm.AverageCalc;
import extend.org.compiere.hrm.AverageSalary;
import extend.org.compiere.hrm.TaxCompute;
import extend.org.compiere.hrm.TaxVariable;
import extend.org.compiere.hrm.TypePayment;
import extend.org.compiere.utils.Util;

public class GenerateReviewPay extends SvrProcess {
	
	/** Review models */
	private Mhrmreview hrmrev = null;
	private Mhrmreviewline revline = null;
	
	/** Order model */
	private Mhrmorder vorder = null;
	private Mhrmorder reforder = null;
	
	/** Tax */
	private TaxVariable taxcomp = null;	
		
	/** Limit holiday */
	private Mhrmlimitholiday limdays = null;
		
	/**	Employee List	*/
	private Mhrmemployee[] m_orderlines;	
	
	double total = 0;
	double SUM = .0;
	int days = 0;
	int workdays = 0;
	BigDecimal average = new BigDecimal(0);
	Timestamp dateFrom = null;
	
	/** Calendar */
	Calendar calendar = Calendar.getInstance(); 
	
	/** Average */
	private AverageSalary avg = null;

	@Override
	protected void prepare() {
		
		hrmrev = new Mhrmreview(getCtx(), getRecord_ID(), null);
	}

	protected String doIt() throws Exception {
		dateFrom = hrmrev.getDateFrom();
		
		if (X_hrm_order.HRM_COMPENSATIONTYPE_Trip.equals(hrmrev.gethrm_compensationtype())){ // командировка
			
//			X_HR_Employee hremp = X_HR_Employee.getHR_Employee(hrmrev.getC_BPartner_ID(),(Boolean) null);
//			revline = Mhrmreviewline.getReviewline(hremp.getC_BPartner_ID(), hrmrev.getDateFrom());
//			if (revline == null || revline.get_ID() == 0)
//				revline = new Mhrmreviewline(getCtx(), 0, get_TrxName());
//			revline.sethrm_review_ID(hrmrev.gethrm_review_ID());
//			revline.setC_BPartner_ID(hremp.getC_BPartner_ID());
//			revline.setHR_Department_ID(hremp.getHR_Department_ID());
//			revline.setHR_Job_ID(hremp.getHR_Job_ID());
//			revline.setStartDate(hrmrev.getDateFrom());
//			SUM = hrmrev.gethrm_total().doubleValue();
//			taxcomp =  TaxCompute.GetTax(hremp.getC_BPartner_ID(), SUM, hrmrev.getDateFrom(), TypePayment.BUSINESSTRIP);
//			revline.sethrm_IPN(new BigDecimal(taxcomp.getIPN()));
//			revline.sethrm_OPV(new BigDecimal(taxcomp.getOPV()));
//			revline.sethrm_COtch(new BigDecimal(taxcomp.getCOTCH()));
//			revline.sethrm_CNalog(new BigDecimal(taxcomp.getCNALOG()));
//			revline.sethrm_total(new BigDecimal(taxcomp.getTOTAL()));
//			revline.sethrm_compensationtype(hrmrev.gethrm_compensationtype());
//			//-----------------------------------------------------------
//			revline.sethrm_orderref_ID(0);
//			revline.sethrm_amountreview(new BigDecimal(0));
//			revline.sethrm_days(0);
//			revline.saveEx();
//			
		}else if (X_hrm_order.HRM_COMPENSATIONTYPE_Profit.equals(hrmrev.gethrm_compensationtype())){
			
			X_HR_Employee hremp = X_HR_Employee.getHR_Employee(hrmrev.getC_BPartner_ID(),(Boolean) null);
			revline = Mhrmreviewline.getReviewline(hremp.getC_BPartner_ID(), hrmrev.getDateFrom());
			if (revline == null || revline.get_ID() == 0)
				revline = new Mhrmreviewline(getCtx(), 0, get_TrxName());
			revline.sethrm_review_ID(hrmrev.gethrm_review_ID());
			revline.setC_BPartner_ID(hremp.getC_BPartner_ID());
			revline.setHR_Department_ID(hremp.getHR_Department_ID());
			revline.setHR_Job_ID(hremp.getHR_Job_ID());
			revline.setStartDate(hrmrev.getDateFrom());
			SUM = hrmrev.gethrm_total().doubleValue();
			taxcomp =  TaxCompute.GetTax(hremp.getC_BPartner_ID(), SUM, hrmrev.getDateFrom(), TypePayment.PAYMENT);
			revline.sethrm_IPN(new BigDecimal(taxcomp.getIPN()));
			revline.sethrm_OPV(new BigDecimal(taxcomp.getOPV()));
			revline.sethrm_COtch(new BigDecimal(taxcomp.getCOTCH()));
			revline.sethrm_CNalog(new BigDecimal(taxcomp.getCNALOG()));
			revline.sethrm_total(new BigDecimal(taxcomp.getTOTAL()));
			revline.sethrm_compensationtype(hrmrev.gethrm_compensationtype());
			//-----------------------------------------------------------
			revline.sethrm_orderref_ID(0);
			revline.sethrm_amountreview(new BigDecimal(0));
			revline.sethrm_days(0);
			revline.saveEx();
			
		}else{
			
			vorder = new Mhrmorder(getCtx(), hrmrev.gethrm_order_ID(), null);			
			m_orderlines = vorder.getLinesEmployee();
			for(int i=0; i < m_orderlines.length; i++){
				average = new BigDecimal(0);
				SUM = 0;
				X_HR_Employee hremp = X_HR_Employee.getHR_Employee(m_orderlines[i].getC_BPartner_ID(),(Boolean) null);
				if (hremp.getC_BPartner_ID() == 0)
					throw new AdempiereException ("Info about employee was empty, may be employee is dismissed ");
				
				limdays = Mhrmlimitholiday.getLimitHoliday(hremp.getC_BPartner_ID(), null);
				
				// record line
				revline = Mhrmreviewline.getReviewline(hremp.getC_BPartner_ID(), vorder.getStartDate());
				if (revline == null || revline.get_ID() == 0)
					revline = new Mhrmreviewline(getCtx(), 0, get_TrxName());
				revline.sethrm_review_ID(hrmrev.gethrm_review_ID());
				revline.setC_BPartner_ID(hremp.getC_BPartner_ID());
				revline.setHR_Department_ID(hremp.getHR_Department_ID());
				revline.setHR_Job_ID(hremp.getHR_Job_ID());
				revline.setStartDate(vorder.getStartDate());
			//	revline.setEndDate(reforder.getEndDate());
				
				/** If employee was review from vacation */
				if (X_hrm_order.HRM_ORDERTYPE_Review.equals(vorder.gethrm_ordertype())){				
					revline.sethrm_orderref_ID(vorder.gethrm_orderref_ID()); 
					reforder = new Mhrmorder(getCtx(), vorder.gethrm_orderref_ID(), null);				
					revline.sethrm_amountreview(reforder.gethrm_average());
					revline.sethrm_compensationtype(vorder.gethrm_compensationtype());
					avg = AverageCalc.getAvarage(hremp.getC_BPartner_ID(), reforder.getDateFrom());
					revline.setDateFrom(avg.getSTARTDATE());
					revline.setDateTo(avg.getENDDATE());
					average = reforder.gethrm_average();
					
					if (reforder.getEndDate().after(vorder.getEndDate()) 
							|| vorder.getEndDate() != null){
						revline.setEndDate(vorder.getEndDate());
						days = Util.getDays(vorder.getStartDate(), vorder.getEndDate());
						workdays = Util.getWorkingDays(hremp.getC_BPartner_ID(), vorder.getStartDate(), vorder.getEndDate());
					}else{
						days = Util.getDays(vorder.getStartDate(), reforder.getEndDate());
						workdays = Util.getWorkingDays(hremp.getC_BPartner_ID(), vorder.getStartDate(), reforder.getEndDate());
					}
					
					revline.sethrm_days(days);
					
					// 1 - with compensation 
					if (!X_hrm_order.HRM_COMPENSATIONTYPE_Compensation.equals(vorder.gethrm_compensationtype())){	// отпуска				
						average = average.multiply(new BigDecimal(workdays));
						revline.sethrm_total(average.negate());					
					//	limdays.sethrm_limitdays(limdays.gethrm_limitdays()+days);
					//	limdays.sethrm_daysused(limdays.gethrm_daysused()-days);
					//	limdays.saveEx();
						SUM = average.doubleValue(); 
					}else{
						revline.sethrm_total(new BigDecimal(0));
						SUM = 0;
					}
					
					// Generate employee tax 
					taxcomp =  TaxCompute.GetTax(hremp.getC_BPartner_ID(), SUM, dateFrom, TypePayment.REVIEW);
					BigDecimal IPN = new BigDecimal(taxcomp.getIPN());
					revline.sethrm_IPN(IPN.negate());
					BigDecimal OPV = new BigDecimal(taxcomp.getOPV());
					revline.sethrm_OPV(OPV.negate());
					//BigDecimal COTCH = new BigDecimal(taxcomp.getCOTCH());
					revline.sethrm_COtch(new BigDecimal(0));
					BigDecimal CNALOG = new BigDecimal(taxcomp.getCNALOG());
					revline.sethrm_CNalog(CNALOG.negate());	
					
				}else if (X_hrm_order.HRM_ORDERTYPE_Dismissal.equals(vorder.gethrm_ordertype())){ // при увольнении
					avg = AverageCalc.getAvarage(hremp.getC_BPartner_ID(), vorder.getStartDate());
					//average = new BigDecimal(avg.getRESULT());
					//days = limdays.gethrm_limitdays();
					
					//--Add by A.Kulantayev
					revline.setStartDate(vorder.getStartDate());
					//Считаем сколько раз он уходил в отпуск за все время что он работал
					Mhrmorder[] vacationOrders = Mhrmorder.getHRMOrderList(X_hrm_order.HRM_ORDERTYPE_Vacation, hremp.getC_BPartner_ID());
					int calendarVacationDays = 0;
					for(int j= 0; j< vacationOrders.length; j++){
						if(vacationOrders[j].gethrm_workleavetype().equals(X_hrm_order.HRM_WORKLEAVETYPE_NormVacation)
								||vacationOrders[j].gethrm_workleavetype().equals(X_hrm_order.HRM_WORKLEAVETYPE_NonNormVacation)){ 
							calendarVacationDays+=Util.getWorkingDays(hremp.getC_BPartner_ID(), vacationOrders[j].getStartDate(), vacationOrders[j].getEndDate());
							
						}
					}
					revline.setEndDate(Util.getDismissalEndDate(vorder.getStartDate(), calendarVacationDays));
					//--
					//revline.sethrm_days(limdays.gethrm_limitdays());
					
					//--add by A.Kulantayev 28/07/2013
					revline.sethrm_days(limdays.gethrm_days().intValue());
					revline.sethrm_calendardays(limdays.gethrm_limitdays());
					//--
					revline.setDateFrom(avg.getSTARTDATE());
					revline.setDateTo(avg.getENDDATE());
					revline.sethrm_amountreview(new BigDecimal(avg.getRESULT()));	
					revline.sethrm_orderref_ID(vorder.gethrm_order_ID()); 
					revline.sethrm_compensationtype(X_hrm_order.HRM_COMPENSATIONTYPE_Dissmissal);
					//average = average.multiply(new BigDecimal(limdays.gethrm_limitdays()));				
					//limdays.sethrm_daysused(limdays.gethrm_daysused()+days);
					//limdays.sethrm_limitdays(0);
					//limdays.sethrm_days(new BigDecimal(0));
					//limdays.setIsActive(false);
					//limdays.saveEx();
					
					// Generate employee tax
					SUM = avg.getRESULT()*limdays.gethrm_limitdays();  
					taxcomp =  TaxCompute.GetTax(hremp.getC_BPartner_ID(), SUM, dateFrom, TypePayment.DISMISSAL);
					revline.sethrm_IPN(new BigDecimal(taxcomp.getIPN()));
					revline.sethrm_OPV(new BigDecimal(taxcomp.getOPV()));
					revline.sethrm_COtch(new BigDecimal(taxcomp.getCOTCH()));
					revline.sethrm_CNalog(new BigDecimal(taxcomp.getCNALOG()));
					revline.sethrm_total(new BigDecimal(taxcomp.getTOTAL()));
				}
				
				revline.saveEx();
				
				Mhrmreservesectional[] line = Mhrmreservesectional.getMhrmreservesectional(); 
				for(Mhrmreservesectional l: line){
					X_hrm_reviewline revLine = Mhrmreviewline.getRevewLineAcct(revline.gethrm_review_line_ID(), l.gethrm_reservesectional_ID());
					if(revLine == null)
						revLine = new X_hrm_reviewline(Env.getCtx(),0,null);
					
					if(l.gethrm_reservesectional_ID() == Mhrmreserve.RESERVE_SECTIONAL_CHARGE){
						if (!X_hrm_order.HRM_COMPENSATIONTYPE_Compensation.equals(vorder.gethrm_compensationtype())){
							revLine.sethrm_amount(revline.gethrm_total().negate());						
						}else{
							revLine.sethrm_amount(revline.gethrm_total());						
						}					
						revLine.sethrm_reservesectional_ID(Mhrmreserve.RESERVE_SECTIONAL_CHARGE);
					}
					else if(l.gethrm_reservesectional_ID() == Mhrmreserve.RESERVE_SECTIONAL_CNALOG){
						if (!X_hrm_order.HRM_COMPENSATIONTYPE_Compensation.equals(vorder.gethrm_compensationtype())){
							revLine.sethrm_amount(revline.gethrm_CNalog().negate());
						}else{
							revLine.sethrm_amount(revline.gethrm_CNalog());
						}
						revLine.sethrm_reservesectional_ID(Mhrmreserve.RESERVE_SECTIONAL_CNALOG);
					}
					else if(l.gethrm_reservesectional_ID() == Mhrmreserve.RESERVE_SECTIONAL_COTCH){
						if (!X_hrm_order.HRM_COMPENSATIONTYPE_Compensation.equals(vorder.gethrm_compensationtype())){
							revLine.sethrm_amount(revline.gethrm_COtch().negate());
						}else{
							revLine.sethrm_amount(revline.gethrm_COtch());						
						}					
						revLine.sethrm_reservesectional_ID(Mhrmreserve.RESERVE_SECTIONAL_COTCH);
					}
					revLine.sethrm_reserve_ID(Mhrmreserve.RESERVE_VACATION);
					revLine.sethrm_review_ID(hrmrev.gethrm_review_ID());
					revLine.sethrm_review_line_ID(revline.gethrm_review_line_ID());
					revLine.saveEx();
				}			
			}
			
		}
		
		return Msg.translate(Env.getCtx(), "Success");
	}

}
